package tt.dz.service.imp.sys;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import tt.dz.dao.ext.system.OmsOperListDao;
import tt.dz.dao.ext.system.OmsOperRoleDao;
import tt.dz.dao.ext.system.OmsUrlListDao;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.base.OmsEntityEnum;
import tt.dz.entity.base.OmsOtherChannel;
import tt.dz.entity.exception.OmsDaoException;
import tt.dz.entity.system.OmsOperList;
import tt.dz.service.imp.base.BaseService;
import tt.dz.service.sys.OtherPartnerService;
import tt.dz.tcp.rpc.ms.SystemMasterServerRpcClient;
import tt.dz.tcp.rpc.ms.client.entity.MasterLoginResult;
import tt.dz.tcp.rpc.ms.client.entity.MasterOtherLoginParam;
import tt.dz.util.ActionUtils;
import tt.dz.util.OmsConstant.MsgCodeEnum;
import tt.dz.util.RedisClient;
@Service @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class OtherPartnerServiceImpl extends BaseService implements OtherPartnerService{
	@Autowired
	private OmsOperListDao operListDao;
	@Autowired
	private OmsUrlListDao urlListDao;
	@Autowired
	private OmsOperListDao operatorDaoImpl;
	@Autowired
	private OmsOperRoleDao operRoleDaoImpl;
//	@Autowired
//	private RedisTemplate<String, String> redisTemplate;
//	private Jedis jedis;
	@Value("${otherLoginKey}")
	private String otherLoginKey;
	@Value("${loginOutTime}")
	private long timeOut;
	@Autowired
	private SystemMasterServerRpcClient msRcp;
	
	@Override
	public JsonCommon<?> partnerLogin(String loginAccount, String password,String channelNo) 
	{
		if (StringUtils.isEmpty(channelNo) || !OmsOtherChannel.hasChannel(channelNo))
		{
			return this.buildOtherJsonCommon(
					MsgCodeEnum.OTHER_LOGIN_CHANNEL_NO_ERROR.getMsgCode(),
					MsgCodeEnum.OTHER_LOGIN_CHANNEL_NO_ERROR.getMsgInfo());
		}
		if (StringUtils.isEmpty(loginAccount) || StringUtils.isEmpty(password))
		{
			return this.buildOtherJsonCommon(
					MsgCodeEnum.REQUEST_PARAM_MISS_ERROR.getMsgCode(),
					MsgCodeEnum.REQUEST_PARAM_MISS_ERROR.getMsgInfo());
		}
		//1、通过登录名获取redis存在的用户 判断用户是否登录
		//ValueOperations<String, String> valueOper = redisTemplate.opsForValue();
		StringBuilder valueKey = new StringBuilder();
		valueKey.append(otherLoginKey).append(":").append(loginAccount);
		//String loginValue = valueOper.get(valueKey.toString());
		String loginValue = RedisClient.get(valueKey.toString());
		if (loginValue != null)
		{
			//获取到的用户登录信息直接返回token
			return this.returnLoginToken(valueKey.toString(), loginValue);
		}
		else
		{
			MasterOtherLoginParam ob = new MasterOtherLoginParam();
			ob.setMobileNo(loginAccount);
			ob.setPassword(password);
			MasterLoginResult loginResult = msRcp.systemOtherLoginInteface(ob);
			if (loginResult == null)
			{
				return this.buildOtherJsonCommon(
						MsgCodeEnum.MS_RPC_ERROR.getMsgCode(),
						MsgCodeEnum.MS_RPC_ERROR.getMsgInfo());
			}
			else if ( loginResult.getIsSuccess() <= 0)
			{
				return this.buildOtherJsonCommon(
						MsgCodeEnum.OTHER_LOGIN_ERROR.getMsgCode(),
						loginResult.getErrorMsg());
			}
			else
			{
				OmsOperList obj = null;
				try 
				{
					obj = operListDao.findRecordByPK(obj);
					if (obj == null)
					{
						obj = new OmsOperList();
						obj.setMs_manager_id(loginResult.getUserId());
						Date now = new Date();
						obj.setAccount(loginAccount);
						obj.setOper_id(genarateLogicOperId(OmsEntityEnum.ENTERPRISE.getValue()));
						obj.setCreate_time(now);
						obj.setLast_time(now);
						obj.setPassword(password);
						obj.setOper_name(loginAccount);
						obj.setEntity_type(OmsEntityEnum.ENTERPRISE.getValue());
						obj.setStatus(1);
						obj.setValid_flag(1);
						operatorDaoImpl.add(obj);
						//给添加用户角色信息
						operRoleDaoImpl.addRoleUserMapping(loginResult.getUserId(), OmsEntityEnum.ENTERPRISE.getValue());
					}
					
					if ( obj.getStatus() <= 0 || StringUtils.isEmpty(obj.getOper_id()))
					{
						return this.buildOtherJsonCommon(
								MsgCodeEnum.OTHER_LOCK_ERROR.getMsgCode(),
								MsgCodeEnum.OTHER_LOCK_ERROR.getMsgInfo());
					}
					else
					{
						List<String> powerUrls = urlListDao.findValidUrlsByManagerId(obj.getMs_manager_id(), "permission");
						if (powerUrls != null && powerUrls.size() > 0)
						{
							obj.setPowerUrls(powerUrls);
						}
						String token = ActionUtils.genarateUserToken(obj);
						//生成用户token
						if (StringUtils.isNotEmpty(token))
						{
							//ListOperations<String, String> opsLst = redisTemplate.opsForList();
							if (powerUrls != null && powerUrls.size() > 0)
							{
								/*redisTemplate.delete(token);
								opsLst.leftPushAll(token, powerUrls.toArray(new String[powerUrls.size()]));*/
								RedisClient.delByKey(token);
								RedisClient.putList(token, powerUrls);
							}
							/*redisTemplate.expire(token, timeOut, TimeUnit.DAYS);
							valueOper.set(valueKey.toString(), token);*/
							RedisClient.expire(token,(int)(timeOut*24*60*60));
							RedisClient.putString(valueKey.toString(), token);
							return this.returnLoginToken(valueKey.toString(), token);
						}
					
					}
				} 
				catch (Exception e) 
				{
					this.logError("partnerLogin error", e);
				}
			}
		}
		
		return this.buildOtherJsonCommon(
				MsgCodeEnum.OTHER_LOGIN_ERROR.getMsgCode(),
				MsgCodeEnum.OTHER_LOGIN_ERROR.getMsgInfo());
		
	
	}
	
	private JsonCommon<String> returnLoginToken(String valueKey,String loginValue)
	{
		//redisTemplate.expire(valueKey.toString(), timeOut, TimeUnit.DAYS);
		RedisClient.expire(valueKey, (int)(timeOut*24*60*60));
		JsonCommon<String> result = this.buildOtherJsonCommon(
				MsgCodeEnum.OTHER_LOGIN_SUCCESS.getMsgCode(),
				MsgCodeEnum.OTHER_LOGIN_SUCCESS.getMsgInfo());
		result.setPojo(loginValue.toString());
		return result;
	}

	@Override
	public JsonCommon<?> partnerOpenApiAuthorization(String authorizationToken,String url) 
	{
		//获取token信息
		if (StringUtils.isEmpty(authorizationToken))
		{
			//如果认证token为null
			return this.buildOtherJsonCommon(
					MsgCodeEnum.OL_REQUEST_PARAM_MISS_ERROR.getMsgCode(),
					MsgCodeEnum.OL_REQUEST_PARAM_MISS_ERROR.getMsgInfo());
		}
		else
		{
			OmsOperList user = ActionUtils.parseUserToken(authorizationToken);
			if (user != null)
			{
				StringBuilder valueKey = new StringBuilder();
				valueKey.append(otherLoginKey).append(":").append(user.getAccount()); 
				//String loginValue = redisTemplate.opsForValue().get(valueKey.toString());
				String loginValue = RedisClient.get(valueKey.toString());
				//判断token是否过期
				if (StringUtils.isNotEmpty(loginValue))
				{
					/*ListOperations<String, String> opsLst = redisTemplate.opsForList();
					List<String> powerUrls = null;
					Long size = opsLst.size(authorizationToken);*/
					List<String> powerUrls = null;
//					Long size = RedisClient.getConnect().llen(authorizationToken);
					Jedis jedis = RedisClient.getConnect();
					Long size = jedis.llen(authorizationToken);
					jedis.close();
					if (size == null || size <= 0)
					{
						try 
						{
							powerUrls = urlListDao.findValidUrlsByManagerId(user.getMs_manager_id(), "permission");
							//redisTemplate.delete(authorizationToken);
							RedisClient.delByKey(authorizationToken);
							if (powerUrls != null && powerUrls.size() > 0)
							{
								/*opsLst.leftPushAll(authorizationToken, powerUrls.toArray(new String[powerUrls.size()]));
								redisTemplate.expire(authorizationToken, timeOut, TimeUnit.DAYS);*/
								RedisClient.putList(authorizationToken, powerUrls);
								RedisClient.expire(authorizationToken, (int)(timeOut*24*60*60));
							}
						} 
						catch (Exception e) 
						{
							this.logError(e.getMessage(), e);
						}
					
					}
					//powerUrls = opsLst.range(authorizationToken, 0, size);
					powerUrls = RedisClient.getList(authorizationToken);
					if (powerUrls != null && powerUrls.size() > 0)
					{ 
						for (String powerUrl : powerUrls)
						{
							if (url.contains(powerUrl))
							{
								user.setPowerUrls(powerUrls);
								//认证成功，时间延后
								/*redisTemplate.expire(valueKey.toString(), timeOut, TimeUnit.DAYS);*/
								RedisClient.expire(valueKey.toString(), (int)(timeOut*24*60*60));
								return this.buildSuccessJsonCommon(user);
							}
						}
					}
					
					return this.buildOtherJsonCommon(
							MsgCodeEnum.OL_NO_POWER_ACCESS_ERROR.getMsgCode(),
							MsgCodeEnum.OL_NO_POWER_ACCESS_ERROR.getMsgInfo());
					
				}
				else
				{
					return this.buildOtherJsonCommon(
							MsgCodeEnum.OL_TOKEN_OUTTIME_ERROR.getMsgCode(),
							MsgCodeEnum.OL_TOKEN_OUTTIME_ERROR.getMsgInfo());
				}
			}
			
			return this.buildOtherJsonCommon(
					MsgCodeEnum.SYSTEM_ERROR.getMsgCode(),
					MsgCodeEnum.SYSTEM_ERROR.getMsgInfo());
			
		}
		
		
	
	}
	
	private String genarateLogicOperId(Integer entityType)throws OmsDaoException
	{
		String maxId = operatorDaoImpl.findMaxLogicOperId(entityType);
		StringBuilder maxsb = new StringBuilder();
		maxsb.append(entityType);
		maxsb.append("000");
		maxsb.append(genarateId(maxId, 13));
		return maxsb.toString();
	}

}
